<template>
  <div class="form-table" ref="scFormTable">
    <el-table
        :data="data"
        ref="table"
        border
        stripe
        :cell-style="{ textAlign: 'center' }"
        :header-cell-style="{
				textAlign: 'center',
				background: 'var(--el-table-row-hover-bg-color)',
				color: 'var(--el-text-color-primary)',
			}"
    >
      <el-table-column type="index" width="50" fixed="left">
        <template #header>
          <el-button v-if="!hideAdd" type="primary" icon="el-icon-plus" size="small" circle @click="rowAdd"></el-button>
          <el-tooltip v-else content="序号" placement="top"> #</el-tooltip>
        </template>
        <template #default="scope">
          <div :class="['form-table-handle', { 'form-table-handle-delete': !hideDelete }]">
            <span>{{ scope.$index + 1 }}</span>
            <el-button
                v-if="!hideDelete"
                type="danger"
                icon="el-icon-delete"
                size="small"
                plain
                circle
                @click="rowDel(scope.row, scope.$index)"
            ></el-button>
          </div>
        </template>
      </el-table-column>
      <el-table-column label="" width="50" v-if="dragSort">
        <template #header>
          <el-icon>
            <el-tooltip content="拖动排序" placement="top">
              <WarningFilled/>
            </el-tooltip>
          </el-icon>
        </template>
        <template #default>
          <div class="move" style="cursor: move">
            <el-icon>
              <Sort/>
            </el-icon>
          </div>
        </template>
      </el-table-column>
      <slot></slot>
      <template #empty>
        {{ placeholder }}
      </template>
    </el-table>
  </div>
</template>

<script>
import Sortable from 'sortablejs';

export default {
  props: {
    /**
     * 表格数据
     */
    modelValue: { type: Array, default: () => [] },
    /**
     * 新增行模板
     */
    addTemplate: {
      type: Object, default: () => {
      }
    },
    /**
     * 无数据时的提示语
     */
    placeholder: { type: String, default: '暂无数据' },
    /**
     * 是否启用拖拽排序
     */
    dragSort: { type: Boolean, default: false },
    /**
     * 是否隐藏新增按钮
     */
    hideAdd: { type: Boolean, default: false },
    /**
     * 是否隐藏删除按钮
     */
    hideDelete: { type: Boolean, default: false },
  },
  data () {
    return {
      /**
       * 表格数据
       */
      data: [],
    };
  },
  mounted () {
    this.data = this.modelValue;
    if (this.dragSort) {
      this.rowDrop();
    }
  },
  watch: {
    modelValue () {
      this.data = this.modelValue;
    },
    data: {
      handler () {
        /**
         * 更新表格数据
         * @event update:modelValue
         * @type {Array}
         */
        this.$emit('update:modelValue', this.data);
      },
      deep: true,
    },
  },
  methods: {
    /**
     * 启用表格行拖拽排序
     */
    rowDrop () {
      const _this = this;
      const tbody = this.$refs.table.$el.querySelector('.el-table__body-wrapper tbody');
      Sortable.create(tbody, {
        handle: '.move',
        animation: 300,
        ghostClass: 'ghost',
        onEnd ({ newIndex, oldIndex }) {
          _this.data.splice(newIndex, 0, _this.data.splice(oldIndex, 1)[0]);
          const newArray = _this.data.slice(0);
          const tmpHeight = _this.$refs.scFormTable.offsetHeight;
          _this.$refs.scFormTable.style.setProperty('height', tmpHeight + 'px');
          _this.data = [];
          _this.$nextTick(() => {
            _this.data = newArray;
            _this.$nextTick(() => {
              _this.$refs.scFormTable.style.removeProperty('height');
            });
          });
        },
      });
    },
    /**
     * 新增一行
     */
    rowAdd () {
      const temp = JSON.parse(JSON.stringify(this.addTemplate));
      this.data.push(temp);
    },
    /**
     * 删除一行
     * @param {Object} row - 要删除的行数据
     * @param {number} index - 要删除的行的索引
     */
    rowDel (row, index) {
      this.data.splice(index, 1);
      this.$emit('delete', row);
    },
    /**
     * 插入一行
     * @param {Object} row - 要插入的行数据，默认为新增行模板
     */
    pushRow (row) {
      const temp = row || JSON.parse(JSON.stringify(this.addTemplate));
      this.data.push(temp);
    },
    /**
     * 根据索引删除一行
     * @param {number} index - 要删除的行的索引
     */
    deleteRow (index) {
      this.data.splice(index, 1);
    },
  },
};
</script>

<style scoped>
.form-table {
  width: 100%;
}

.form-table .form-table-handle {
  text-align: center;
}

.form-table .form-table-handle span {
  display: inline-block;
}

.form-table .form-table-handle button {
  display: none;
}

.form-table .hover-row .form-table-handle-delete span {
  display: none;
}

.form-table .hover-row .form-table-handle-delete button {
  display: inline-block;
}

.form-table .move {
  text-align: center;
  font-size: 14px;
  margin-top: 3px;
}
</style>
